#include "stdafx.h"
#include "Utility.h"
#include "InputSniffer.h"
#include <sstream>
#include "MemTrack.h"

namespace bs
{
	InputSniffer::InputSniffer(HWND hwnd)
		: hwnd(hwnd), lBtnDown(false), rBtnDown(false), mBtnDown(false),
		lBtnClk(false), rBtnClk(false), mBtnClk(false)
	{
		::memset(this->keyStatus, false, sizeof(this->keyStatus));

		this->cursorScrPos = Point(0, 0);
		this->cursorWinPos = Point(0, 0);
	}

	InputSniffer::~InputSniffer()
	{
	}

	void InputSniffer::Sniff(const MSG& msg)
	{
		switch(msg.message)
		{
		case WM_LBUTTONDOWN:
			this->lBtnDown = true;
			return;

		case WM_LBUTTONUP:
			this->lBtnClk = this->lBtnDown ? true : false;
			this->lBtnDown = false;
			return;

		case WM_RBUTTONDOWN:
			this->rBtnDown = true;
			return;

		case WM_RBUTTONUP:
			this->rBtnClk = this->rBtnDown ? true : false;
			this->rBtnDown = false;
			return;

		case WM_MBUTTONDOWN:
			this->mBtnDown = true;
			return;

		case WM_MBUTTONUP:
			this->mBtnClk = this->mBtnDown ? true : false;
			this->mBtnDown = false;
			return;

		case WM_KEYDOWN:
		case WM_SYSKEYDOWN:
			this->keyStatus[msg.wParam] = true;
			return;

		case WM_KEYUP:
		case WM_SYSKEYUP:
			this->keyStatus[msg.wParam] = false;
			return;
		}

		if(msg.message>=WM_MOUSEFIRST && msg.message<=WM_MOUSELAST)
		{
			this->cursorWinPos.x = (int)(msg.lParam & 0xFFFF);
			this->cursorWinPos.y = (int)(msg.lParam >> 16);
		}
	}

	void InputSniffer::ClearBuffer()
	{
//		::ZeroMemory(this->keyStatus, MAX_KEY_SIZE*sizeof(bool));

// 		this->lBtnDown = false;
// 		this->rBtnDown = false;
// 		this->mBtnDown = false;
		this->lBtnClk = false;
		this->rBtnClk = false;
		this->mBtnClk = false;

// 		this->cursorScrPos.x = this->cursorScrPos.y = 0;
// 		this->cursorWinPos.x = this->cursorWinPos.y = 0;
	}

	const Point& InputSniffer::GetCursorScreenPos()
	{
		POINT pt;
		::GetCursorPos(&pt);

		this->cursorScrPos.x = pt.x;
		this->cursorScrPos.y = pt.y;

		::ScreenToClient(this->hwnd, &pt);

		this->cursorWinPos.x = pt.x;
		this->cursorWinPos.y = pt.y;

		return this->cursorScrPos;
	}

	std::string InputSniffer::DumpInput()
	{
		this->GetCursorScreenPos();

		std::stringstream ss;

		ss << "\n";

		for(int i=0; i<MAX_KEY_SIZE; ++i)
		{
			ss << "key " << i << ":  " << (this->keyStatus[i] ? "down" : "Clk") << "\n";
		}

		ss << "LBtn :  " << (this->lBtnDown ? "down" : "Clk") << "\n";
		ss << "RBtn :  " << (this->rBtnDown ? "down" : "Clk") << "\n";
		ss << "MBtn :  " << (this->mBtnDown ? "down" : "Clk") << "\n";

		ss << "CursorScrPos:  x: " << this->cursorScrPos.x << "  y: " << this->cursorScrPos.y << "\n";
		ss << "CursorWinPos:  x: " << this->cursorWinPos.x << "  y: " << this->cursorWinPos.y << "\n";

		return ss.str();
	}

}